﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using blackhouse.AsyncMail.Business.Data;
using System.Xml.Serialization;
using System.IO;
using System.Net.Mail;
using System.Configuration;

using blackhouse;

namespace blackhouse.AsyncMail.Business {
    public class ASyncMail {

        #region Fields

        private IASyncMailDataAccess data;

        #endregion

        #region Properties

        public int RequestId { get; private set; }
        public MailAddress Receiver { get; private set; }
        public string MessageTitle { get; private set; }
        public int TemplateId { get; private set; }
        public object BindObject { get; private set; }
        public Type BindType { get; private set; }
        public DateTime SetTime { get; private set; }

        #endregion

        #region Constructors

        public ASyncMail(IASyncMailDataAccess dataAccess) {
            this.data = dataAccess;
        }

        public ASyncMail(IASyncMailDataAccess dataAccess, int templateId, object bindObject, Type bindType, MailAddress receiver, string messageTitle) {
            this.data = dataAccess;
            this.TemplateId = templateId;
            this.BindObject = bindObject;
            this.BindType = bindType;
            this.Receiver = receiver;
            this.MessageTitle = messageTitle;
        }

        #endregion

        #region Methods

        public void Save() {
            this.RequestId = this.data.SaveMail(TemplateId, this.SerializeBindObject(this.BindType, this.BindObject), BindType, this.Receiver.Address, this.Receiver.DisplayName, this.MessageTitle);
        }

        private string SerializeBindObject(Type type, object bindObject) {
            XmlSerializer serializer = new XmlSerializer(type);
            StringWriter sw = new StringWriter();
            serializer.Serialize(sw, bindObject);
            return sw.ToString();
        }

        private object DeserializeBindObject(string serialized, Type type) {
            XmlSerializer serializer = new XmlSerializer(type);
            StringReader sr = new StringReader(serialized);
            return serializer.Deserialize(sr);
        }

        public bool FillByTop() {
            ASyncMailData data = this.data.GetTopMail();
            if (data.RequestId > 0) {
                this.BindType = Type.GetType(data.Type, false);
                if (BindType == null) return false;

                this.BindObject = this.DeserializeBindObject(data.Object, this.BindType);
                this.Receiver = new MailAddress(data.ReceiverMail, data.ReceiverDisplayName);
                this.RequestId = data.RequestId;
                this.TemplateId = data.TemplateId;
                this.SetTime = data.SetTime;
                this.MessageTitle = data.MessageTitle;
                return true;
            }
            return false;
        }

        public bool FillByRequestId(int requestId) {
            ASyncMailData data = this.data.GetMailByRequest(requestId);
            if (data.RequestId > 0) {
                this.BindType = Type.GetType(data.Type, false);
                if (BindType == null) return false;

                this.BindObject = this.DeserializeBindObject(data.Object, this.BindType);
                this.Receiver = new MailAddress(data.ReceiverMail, data.ReceiverDisplayName);
                this.RequestId = data.RequestId;
                this.TemplateId = data.TemplateId;
                this.SetTime = data.SetTime;
                this.MessageTitle = data.MessageTitle;
                return true;
            }
            return false;
        }

        public void MarkAsSended() {
            this.data.MarkAsSended(this.RequestId);
        }

        public void MarkSendError(string errorMessage) {
            this.data.MarkSendError(this.RequestId, errorMessage);
        }

        public MailAddress GetReceiver() {
            MailAddress addr = this.Receiver;
            string email = ConfigurationManager.AppSettings["RedirectAsyncMails"];
            if (!String.IsNullOrEmpty(email) && email.IsValidEmail())
                addr = new MailAddress(email);
            return addr;
        }

        #endregion

    }
}
